#!/usr/bin/env python
#-*- coding:utf-8 -*-
import os,sys,types
from wwpy.util.Logger import logger
from wwpy.util.Wrapper import locker

class Writer(object):
    
    def __init__(self):
        self._info=None
        self._sep='\t'
        self._kv_sep=':'
        self._line_sep='\n'
        self._output='writer_output.txt'
        self._db='db_base_dict'
        
    def info(self,info=None):
        if info is not None:
            self._info=info
        return self._info
    
    def sep(self,sep=None):
        if sep is not None:
            self._sep=sep
        return self._sep
    
    def kv_sep(self,kv_sep=None):
        if kv_sep is not None:
            self._kv_sep=kv_sep
        return self._kv_sep
        
    def line_sep(self,line_sep=None):
        if line_sep is not None:
            self._line_sep=line_sep
        return self._line_sep
    
    def output(self,output=None):
        if output is not None:
            self._output=output
        return self._output
    
    def read(self,source):
        from wwpy.io.Reader import reader
        return reader.read(source)
    
    def handler(self,item):
        if isinstance(item,basestring):
            return item
        elif isinstance(item,(tuple,list,set)):
            return self._sep.join(self.handler(it) for it in item)
        elif isinstance(item,dict):
            return self._sep.join("%s%s%s" % (k,self._kv_sep,v) for k,v in item.items())
        else:
            return str(item)
        
    def check_info(self):
        info=self.info()
        from wwpy.io.Reader import Reader,reader
        if isinstance(info,basestring):
            info=info.strip()
            from wwpy.io.Source import Source
            s=Source(info)
            if any([s.is_dir,s.is_file,s.is_sql,s.is_url]):
                return self.info(self.read(info))
            else:
                return self.info([info])
        elif isinstance(info,(int,long,float)):
            return self.info([info])
        elif isinstance(info,(tuple,list,dict,set)):
            return self.info()
        elif hasattr(info,'next'):
            return self.info()
        elif isinstance(info,Reader):
            return self.info(info.lines)
        else:
            raise Exception('Info type must be string or number or iterator.')
        return self.info()
    
    def write(self):
        self.check_info()
	if isinstance(self._output,basestring):
            logger.info("Write info into %s" % str(self._output))
        def do_write(f):
            for line in self._info:
                self.write_line(f,line)
        if isinstance(self._output,file) or type(self._output) is types.InstanceType:
            do_write(self._output)
        else:
            with open(self._output,'w') as f:
                do_write(f)
                
    @locker
    def write_line(self,f,line):
        line=self.handler(line)
        if not line.endswith(self._line_sep):
            line+=self._line_sep
        f.write(line)
        
    def db(self,db=None):
        if db is not None:
            self._db=db
        return self._db
    
    def copy(self,from_,to_):
        logger.info("Copy from %s to %s" % (from_,to_))
        self.info(from_)
        self.output(to_)
        self.write()
        
writer=Writer()
